# JavaScript 之面向对象

# 一、基础概念

# 1.1 面向对象的实现

JavaScript 不区分类与对象实例,是通过原型来实现面向对象。

var Student = {
    name: "student",
    height: "1.4",
    run: function() {
        console.log(this.name + " is running");
    }
};


var xiaoyun = {
    name: "xiaoyun"
};

xiaoyun.__proto__ = Student;

console.log(xiaoyun.name); // output: xiaoyun
xiaoyun.run(); // output: xiaoyun is running
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Student不是一个类,是一个对象,xiaoyun 这个对象通过原型仿佛继承 Student 这个对象。

使用 obj.__proto__已经不推荐使用了,这里用于学习。

JavaScript运行期间,xiaoyun可以指向任意其他对象。

var Student = {
    name: "student",
    height: "1.4",
    run: function() {
        console.log(this.name + " is running");
    }
};


/**
 * 创建学生对象
 * @param {*} name 新对象的姓名
 * @returns 
 */
function createStudent(name) {
    // 基于 Student 原型创建一个新对象:
    var s = Object.create(Student);
    // 初始化新对象:
    s.name = name;
    return s;
}

var xiaoyun = createStudent('xiaoyun');
console.log(xiaoyun.name); // output: xiaoyun
xiaoyun.run(); // output: xiaoyun is running
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 1.2 原型的概念

JavaScript 的每一个对象都有一个原型,指向它的原型对象。 我们使用 obj.xxx 访问 xxx 属性时,会首先在当前 obj 对象上查找这个属性,查找不到时,就一直往上查找,一直到 Object.prototype 对象,如果此时还没有找到,那么就返回最终结果 undefined

如果原型链很长,访问一个对象花在查询的时间过多而使程序变得很慢,因此要注意不要把原型链弄得太长。

# 1.3 通过构造函数创建对象

/**
 * 定义一个构造函数
 * 
 * @param {*} name 
 */
function Student(name) {
    this.name = name;
    this.hello = function () {
        console.log('Hello, ' + this.name + '!');
    }
}

var xiaoyun = new Student('小云');
console.log(xiaoyun.name); // output: '小云'
xiaoyun.hello(); // output: Hello, 小云!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

通过 new 的方式,绑定的 this 指向新创建的对象,并默认返回 this。 用 new Student() 创建的对象还从原型上获得了一个 constructor 属性,它指向函数 Student 本身。